import ch.qos.logback.core.encoder.ByteArrayUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import test.GBT32960Serversss;

import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GBT32960Client {

    private final String host;
    private final int port;

    public GBT32960Client(String host, int port) {
        this.host = host;
        this.port = port;
    }

//    private static void ppp (){
//        // 构建一个示例数据包
//        byte[] vin = "12345678901234567".getBytes();  // 示例VIN码
//        byte[] data = "12345678901234567".getBytes();
////
//        GBT32960Message message = new GBT32960Message(
//                CommandType.REAL_TIME_INFORMATION,
//                ResponseTag.SUCCESS,
//                vin,
//                EncryptionType.NONE,
//                data.length,
//                data,
//                calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
//        );
//        System.out.println(JSON.toJSONString(message));
////
////                // 编码并发送数据包
//        byte[] encodedMessage = encodeMessage(message);
////                out.write(encodedMessage);
//        JSONObject authDto = new JSONObject();
//        authDto.put("userNme","1");
//        authDto.put("password","2");
//        List<String> list = new ArrayList<>();
//        list.add("test0001");
//        authDto.put("code","car");
//        authDto.put("sns",list);
////                out.write(authDto.toJSONString().getBytes(StandardCharsets.UTF_8));
////                out.flush();
//        System.out.println(Arrays.toString(encodedMessage));
//    }
public byte[] convertToByteArray(String str) {
    byte[] byteArray = new byte[17];
    byte[] strBytes = str.getBytes();

    for (int i = 0; i < byteArray.length && i < 17; i++) {
        if (i>=strBytes.length){
            byteArray[i] = 0x00;
        }else {
            byteArray[i] = strBytes[i];
        }

    }

    return byteArray;
}
    public void start() {

//        ppp();
        try (Socket socket = new Socket(host, port);
             OutputStream out = socket.getOutputStream()) {
            boolean flag = false;
            while (true){
                // 构建一个示例数据包
                byte[] vin = convertToByteArray("23423411222343225");  // 示例VIN码

                byte[] data = DeviceInfo.build();
                System.out.println(new String(vin));
//
                GBT32960Message message = new GBT32960Message(
                        CommandType.REAL_TIME_INFORMATION,
                        ResponseTag.SUCCESS,
                        vin,
                        EncryptionType.NONE,
                        data.length,
                        data,
                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
                );
//                System.out.println(JSON.toJSONString(message));
//
//                // 编码并发送数据包
                byte[] encodedMessage = encodeMessage(message);
//                out.write(encodedMessage);

                if (!flag){
                    JSONObject authDto = new JSONObject();
                    authDto.put("userNme","1");
                    authDto.put("password","2");
                    List<String> list = new ArrayList<>();
                    list.add("car0001");
                    authDto.put("code","car");
                    authDto.put("sns",list);
//                    out.write(authDto.toJSONString().getBytes(StandardCharsets.UTF_8));
//                    out.flush();

                    Thread.sleep(1000);
                    flag = true;
                }
                String aa = ByteArrayUtil.toHexString(encodedMessage);

//                byte[] test = ByteArrayUtil.hexStringToByteArray(aa);
//                System.out.println(ByteArrayUtil.toHexString(test));
                GBT32960Serversss gbt32960Serversss = new GBT32960Serversss();
                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
//                Thread.sleep(1000);
//
//
                data = DeviceInfo.build02moto();
//
                message = new GBT32960Message(
                        CommandType.REAL_TIME_INFORMATION,
                        ResponseTag.SUCCESS,
                        vin,
                        EncryptionType.NONE,
                        data.length,
                        data,
                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
                );

                encodedMessage = encodeMessage(message);
                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
//                Thread.sleep(1000);
//
//                data = DeviceInfo.build03();
////
//                message = new GBT32960Message(
//                        CommandType.REAL_TIME_INFORMATION,
//                        ResponseTag.SUCCESS,
//                        vin,
//                        EncryptionType.NONE,
//                        data.length,
//                        data,
//                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
//                );
//
//                encodedMessage = encodeMessage(message);
//                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
//                Thread.sleep(1000);
//
//                data = DeviceInfo.build04();
////
//                message = new GBT32960Message(
//                        CommandType.REAL_TIME_INFORMATION,
//                        ResponseTag.SUCCESS,
//                        vin,
//                        EncryptionType.NONE,
//                        data.length,
//                        data,
//                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
//                );
//
//                encodedMessage = encodeMessage(message);
//                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
//                Thread.sleep(1000);
//
//                data = DeviceInfo.build05Location();
////
//                message = new GBT32960Message(
//                        CommandType.REAL_TIME_INFORMATION,
//                        ResponseTag.SUCCESS,
//                        vin,
//                        EncryptionType.NONE,
//                        data.length,
//                        data,
//                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
//                );
//
//                encodedMessage = encodeMessage(message);
//                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
//                Thread.sleep(1000);
//
//                data = DeviceInfo.build06();
////
//                message = new GBT32960Message(
//                        CommandType.REAL_TIME_INFORMATION,
//                        ResponseTag.SUCCESS,
//                        vin,
//                        EncryptionType.NONE,
//                        data.length,
//                        data,
//                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
//                );
//
//                encodedMessage = encodeMessage(message);
//                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
//                Thread.sleep(1000);
//
//                data = DeviceInfo.build07();
////
//                message = new GBT32960Message(
//                        CommandType.REAL_TIME_INFORMATION,
//                        ResponseTag.SUCCESS,
//                        vin,
//                        EncryptionType.NONE,
//                        data.length,
//                        data,
//                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
//                );
//
//                encodedMessage = encodeMessage(message);
//                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
//                out.write(encodedMessage);
//                out.flush();
                Thread.sleep(1000);

                ByteBuf byteBuf = Unpooled.buffer();
                byteBuf.writeBytes(DeviceInfo.build());
                byteBuf.writeBytes(DeviceInfo.build02moto());
                byteBuf.writeBytes(DeviceInfo.build03());
                byteBuf.writeBytes(DeviceInfo.build04());
                byteBuf.writeBytes(DeviceInfo.build05Location());
                byteBuf.writeBytes(DeviceInfo.build06());
                byteBuf.writeBytes(DeviceInfo.build07());
                data = new byte[byteBuf.readableBytes()];
                byteBuf.readBytes(data);
                byteBuf.release();

//data
                message = new GBT32960Message(
                        CommandType.REAL_TIME_INFORMATION,
                        ResponseTag.SUCCESS,
                        vin,
                        EncryptionType.NONE,
                        data.length,
                        data,
                        calculateChecksum(GBT32960Message.getStartBit(), CommandType.REAL_TIME_INFORMATION.getValue(), ResponseTag.SUCCESS.getValue(), vin, EncryptionType.NONE.getValue(), data.length, data)
                );

                encodedMessage = encodeMessage(message);
                gbt32960Serversss.deviceDataToProtocol(encodedMessage);
                out.write(encodedMessage);
                out.flush();
                Thread.sleep(1000*10);

//                return;
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static byte calculateChecksum(byte[] startBit, byte commandType, byte responseTag, byte[] vin, byte encryptionType, int length, byte[] data) {
        byte sum = 0;
        for (byte b : startBit) {
            sum ^= b;
        }
        sum ^= commandType;
        sum ^= responseTag;
        for (byte b : vin) {
            sum ^= b;
        }
        sum ^= encryptionType;
        sum ^= length;
        for (byte b : data) {
            sum ^= b;
        }
        return sum;
    }

    private static byte[] encodeMessage(GBT32960Message message) {
        ByteBuffer buffer = ByteBuffer.allocate(24 + message.getLength() + 1);
        buffer.put(GBT32960Message.getStartBit());
        buffer.put(message.getCommandType().getValue());
        buffer.put(message.getResponseTag().getValue());
        buffer.put(message.getVin());
        buffer.put(message.getEncryptionType().getValue());
        buffer.putShort((short) message.getLength());
        buffer.put(message.getData());
        buffer.put(message.getCheckSum());

        byte[] data=  buffer.array();

        String aa = ByteArrayUtil.toHexString(data);
        System.out.println(aa);
        return data;
    }

    public static void main(String[] args) {
        new GBT32960Client("127.0.0.1", 10002).start();
    }
}
